/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package 解析.node.node;

import 解析.node.others.TreeInfo;
import 解析.ASCII;
import 解析.Matcher;

/**
 *
 * @author yanxi
 */
public class CIBackRef extends Node {

    public int groupIndex;
    public boolean doUnicodeCase;

    public CIBackRef(int groupCount, boolean doUnicodeCase) {
        super();
        groupIndex = groupCount + groupCount;
        this.doUnicodeCase = doUnicodeCase; 
    }
    
    @Override
    public boolean match(Matcher matcher, int i, CharSequence seq) {
        int j = matcher.groups[groupIndex];
        int k = matcher.groups[groupIndex + 1];

        int groupSize = k - j;

        // If the referenced group didn't match, neither can this
        if (j < 0) {
            return false;
        }

        // If there isn't enough input left no match
        if (i + groupSize > matcher.to) {
            matcher.hitEnd = true;
            return false;
        }

        // Check each new char to make sure it matches what the group
        // referenced matched last time around
        int x = i;
        for (int index = 0; index < groupSize; index++) {
            int c1 = Character.codePointAt(seq, x);
            int c2 = Character.codePointAt(seq, j);
            if (c1 != c2) {
                if (doUnicodeCase) {
                    int cc1 = Character.toUpperCase(c1);
                    int cc2 = Character.toUpperCase(c2);
                    if (cc1 != cc2
                            && Character.toLowerCase(cc1)
                            != Character.toLowerCase(cc2)) {
                        return false;
                    }
                } else {
                    if (ASCII.toLower(c1) != ASCII.toLower(c2)) {
                        return false;
                    }
                }
            }
            x += Character.charCount(c1);
            j += Character.charCount(c2);
        }

        return next.match(matcher, i + groupSize, seq);
    }

    @Override
    public boolean study(TreeInfo info) {
        info.maxValid = false;
        return next.study(info);
    }
    
    @Override
    public String toString(){
        return "["+this.getClass().getName()+"]"+"groupIndex:"+groupIndex+","+doUnicodeCase;
    }
}
